package com.msconfig.io;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;

import com.msconfig.utils.GeneralUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.UUID;


//蓝牙IO
public class BlueToothIo extends DataIoInterface {
	public static final String debugName ="/MSConfigDebugFile.txt";
	private Date date;
	public SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);

	private static final Object mLock = new Object();
	//蓝牙类的具体实现核心成员;
	private BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
	//蓝牙类的具体数据核心成员;
	private BluetoothSocket mTransferSocket = null;
	//当前连接的蓝牙地址;
	private String mstrName = "";		// 当前连接用到的IP地址;
	private String mstrAddress = "";	// 当前连接用到的IP地址;
	//读取线程;
	private ReadThread mReadThread = null;
	//发送线程
    private SendStringThread mSendStringThread = null;
	//从数据核心成员拿到的输入输出
	private InputStream mInputStream = null;
	private OutputStream mOutputStream = null;

	//获得连接设备的类型-蓝牙、wifi
	@Override
	public DeviceLinkerType getDeviceType() {
		return DeviceLinkerType.BLUETOOTH;
	}

	//设置要连接设备的地址
	@Override
	public boolean setDevice(String strDevice) {
		String[] strings = strDevice.split("\\|");
		if (strings.length == 2) {
			mstrName = strings[0];
			mstrAddress = strings[1];
			return true;
		}
		return false;
	}
	
	@Override
	public String getDevice() {
		if (mstrAddress.length() == 0) {
			return "";
		}
		return String.format("%s|%s", mstrName, mstrAddress);
	}

    //连接设备
	@Override
	public void connect() {
		if(mstrAddress.length() == 0 || !mstrAddress.contains(":")) {
			if (null != mConnectListener)
				mConnectListener.OnConnectCallBack(false);
			return;
		}
		lodDebug("start connecting....:"+getDeviceType().toString());
		try {
			//根据地址获取BluetoothDevice
			final BluetoothDevice device = mBtAdapter.getRemoteDevice(mstrAddress);
		    new Thread(new Runnable()
			{
				@Override
				public void run()
				{
					lodDebug("thread connect start...");
					synchronized (mLock)
					{
						try
						{
							//获得连接的socket
							mTransferSocket = getTransferSocket(device);
							if (mTransferSocket == null)
							{
								lodDebug("create socket failed....");
			  					if (null != mConnectListener)
									mConnectListener.OnConnectCallBack(false);
								return;
							}
							long nStartMillTime = System.currentTimeMillis();
							try
							{
								lodDebug("bluetooth connecting....");
								mTransferSocket.connect();
							}
							catch (Exception e1)
							{
								try
								{
									mTransferSocket.close();
								}
								catch (Exception e2)
								{
									e2.printStackTrace();
								}
								//等待一定时间
								mTransferSocket = null;
								lodDebug( "connect failed....");
								try
								{
									long havePassTime = System.currentTimeMillis() - nStartMillTime;
									if (havePassTime < 6000)
									{
										Thread.sleep(7000-havePassTime);
									}
								}
								catch (InterruptedException e)
								{
									e.printStackTrace();
								}
							}

							//连接失败
							if (mTransferSocket == null)
							{
								if (null != mConnectListener)
									mConnectListener.OnConnectCallBack(false);
								return;
							}

							try
							{
								mInputStream = mTransferSocket.getInputStream();
								mOutputStream = mTransferSocket.getOutputStream();
								lodDebug( "start readThread....");
								mReadThread = new ReadThread();
								mReadThread.start();

                                // 开启接受数据的线程;
                                //开启发送线程
                                if (mSendStringThread != null) {
                                    mSendStringThread.interrupt();
                                    mSendStringThread = null;
                                }

                                mSendStringThread = new SendStringThread();
                                mSendStringThread.start();

								if (null != mConnectListener) {
									try {
										Thread.sleep(150);
									}catch (InterruptedException e){}
									mConnectListener.OnConnectCallBack(mTransferSocket.isConnected());
								}
								lodDebug("connect succeed.");
							}
							catch (Exception e1)
							{
								// 断开连接;
								try
								{
									if (mTransferSocket != null)
										mTransferSocket.close();
									if (mInputStream != null)
										mInputStream.close();
									if (mOutputStream != null)
										mOutputStream.close();
								}
								catch (Exception e2)
								{
									e2.printStackTrace();
								}
								lodDebug("start ReadThread failed....");

								mTransferSocket = null;
								mInputStream = null;
								mOutputStream = null;
								e1.printStackTrace();

								if (null != mConnectListener)
									mConnectListener.OnConnectCallBack(false);
							}
						}
						catch (Exception e)
						{
							lodDebug("connect Exception:"+e.toString());
							disConnect();
							// 总体异常;
							if (null != mConnectListener)
								mConnectListener.OnConnectCallBack(false);
						}
					}
				}//run()
			}).start();
		} catch (Exception e) {
			lodDebug("Exception:"+e.toString());
		}
	}

	//根据device获得BluetoothSocket
	private BluetoothSocket getTransferSocket(BluetoothDevice device) {
		try
		{
			return device.createRfcommSocketToServiceRecord(
				UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
		}
		catch (IOException e1)
		{
			return null;
		}
	}

	//读取数据
	class ReadThread extends Thread {
		public void run(){
			int nMaxBufLength = 1024;
			byte[] buffer = new byte[nMaxBufLength];
			int byteRead = -1;

			lodDebug("ReadThread: start");

			synchronized (mLock){
				while(isConnected()&&!isInterrupted()){
					try{
					    if(mInputStream != null){
					        byteRead = mInputStream.read(buffer);
							//BufferedInputStream bis = new BufferedInputStream(buffer);
							if(byteRead > 0 && byteRead <= buffer.length){
								try {
									if(mReceiverListener != null)
										mReceiverListener.OnReceiverCallBack(byteRead, buffer);
								}catch (Exception e){
									//String strDebugLogPath = StringFunction.formatDate("yyyyMMdd", new Date(System.currentTimeMillis())) + "_error.log";
									//DebugFileManage.log(strDebugLogPath, e.toString());
								}
						    }
						    else /*if (byteRead < 0 || byteRead > buffer.length)*/ {
								lodDebug("read error disconnect(device).");
								// 连接已断开 ;
								disConnect();
								break;
							}

							if (byteRead < 20) {
								try {
									Thread.sleep(100);
								} catch (InterruptedException e) {
									e.printStackTrace();
								}
							}
						}
						else {
							break;
						}
					}catch (IOException e)
					{
						lodDebug("read IOException disconnect(device)."+e.toString());
						// 连接已断开;
						disConnect();
						break;
					}
					catch (Exception e)
					{
						lodDebug("read Exception disconnect(device)."+e.toString());
						// 连接已断开;
						disConnect();
						break;
					}
				}//while(!isInterrupted())
			}//synchronized (mLock)

			lodDebug("ReadThread: end");
		}
	}

	//外部调用的发送数据方法
	@Override
	public boolean sendData(int nLength, byte[] data){
		if(mOutputStream == null || nLength<= 0)return false;
		try {
			byte[] des=new byte[nLength];
			System.arraycopy(data, 0, des, 0, nLength);
			if(mSendStringThread!=null&&!mSendStringThread.isInterrupted()){
				return mSendStringThread.sendData(des);
			}
		}catch (Exception e){
			lodDebug("sendData:" + e.toString());
		}

		return false;
	}

	//发送线程
    private class SendStringThread extends Thread {
        List<byte[]> listCommand=new ArrayList<>();		//发送队列
        Object sendLock=new Object();

        boolean sendData(byte[] bSend){
            synchronized(sendLock) {
            	//防止队列数据太多
            	if (listCommand.size() > 600)
            		return false;
                if (bSend != null && bSend.length != 0) {
                    listCommand.add(bSend);        //添加到发送队列之后
                    return true;
                }else {
                    return false;
                }
            }
        }

        @Override
        public void run() {
            while (isConnected()&&!isInterrupted()){
                if (mTransferSocket != null&&listCommand.size()>0)
                {
                    byte[] strCurrentSend;
                    synchronized (sendLock) {
                        strCurrentSend= listCommand.get(0);
                        listCommand.remove(0);        //移除最前发送数据
                    }

                    try
                    {
                        if (mTransferSocket.isConnected())
                        {
                            // 向输出流写数据
                            byte[] buffer = strCurrentSend;
                            if(buffer!=null&&buffer.length>0) {
                                mOutputStream.write(buffer);
                                mOutputStream.flush();
                            }
                        }
                    }
                    catch (Exception e)
                    {
						lodDebug("sendData Thread:" + e.toString());
						try {
							if (mTransferSocket.isConnected()) {
								mTransferSocket.close();
								if (mInputStream != null) {
									mInputStream.close();
									mInputStream = null;
								}

								if (mOutputStream != null) {
									mOutputStream.close();
									mOutputStream = null;
								}
							}
						}
						catch (Exception e1) {
							e1.printStackTrace();
						}
						e.printStackTrace();
                    }
                }
                else {
                    try {
                        sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

	//是否已连接
	@Override
	public boolean isConnected() {
		try{
			if (mTransferSocket != null) {
				return mTransferSocket.isConnected();
			}
		}catch (Exception e){}
		return false;
	}
	
	// 断开蓝牙;
	@Override
	public void disConnect(){
		if (null != mConnectListener)
			mConnectListener.OnDisConnectCallBack();

		lodDebug("connect disConnect!");
		mConnectListener = null;

		// 取消所有连接;
		if(mTransferSocket != null){
			try {
				mTransferSocket.close();
				if (mInputStream != null)
					mInputStream.close();
				if (mOutputStream != null)
					mOutputStream.close();
				mInputStream = null;
				mOutputStream = null;
				mTransferSocket = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
			catch (Exception e) {
			}
		}

		//结束读线程
		if(mReadThread != null){
			mReadThread.interrupt();
			mReadThread = null;
		}

        //结束发送线程
        if(mSendStringThread != null){
            mSendStringThread.interrupt();
            mSendStringThread=null;
        }

	}

	@Override
	public void lodDebug(String strLog){
		date = new Date();
		GeneralUtil.writeMessageToFile(simpleDateFormat.format(date) + ":"+strLog+"\r\n", debugName);

	}
}
